package com.googlecode.droidircclient;
/* =================================================
 * Droid IRC Client
 * Authors: Kevin Garton, Dennis McWherter
 * 12 September 2011
 * =================================================*/

import java.io.IOException;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Handler;
import android.widget.TextView;

import com.googlecode.droidircclient.Sockets.*;

public class ReaderThread extends Thread {
	private ClientSocket Sock;
	private Handler Handle;
	private DroidIRCClientActivity Activity;
	private static String TempStr;
	private static String line=null;
	private static String target=null;
	private static String ServerName;
	private static boolean first = true; //we get the server name from the first message it sends us
	private SharedPreferences Prefs;
	private boolean Login;
	private boolean NameReq;
	
	/**
	 * Constructor
	 * 
	 * @param sock
	 * @param handle
	 * @param activity
	 */
	public ReaderThread(ClientSocket sock, Handler handle, SharedPreferences prefs, Activity activity) {
		Sock = sock;
		Handle = handle;
		Activity = (DroidIRCClientActivity)activity;
		Prefs = prefs;
		Login = false;
		NameReq = false;
	}

	/**
	 * run
	 * Thread start routine
	 */
	public void run() {
		while(Sock.isValid()){ // This loop will continuously read from a valid socket
			TempStr = Sock.read();
			if(TempStr == null) continue;
			TempStr.trim();

			if(TempStr.length() > 0) {
				System.out.println("Server Message|"+TempStr); // Print to console
				// parse
				interpret();
				if(NameReq) { /* Are we looking for names? */
					Sock.write("NAMES");
					NameReq = false;
				}
				Handle.post(new Runnable() {
					@Override
					public void run() {
						//handle PING/PONG
						if(TempStr.substring(0,6).equals("PING :")){
							Sock.write("PONG :" + TempStr.substring(6,TempStr.length()));
							return;
						}
						if(line != null && target != null)Activity.updateOutput((line + '\n'),target);
						else{
							Activity.updateOutput(TempStr + '\n');
						}
						Activity.updateScroll();
					}
				});
				
				// Temporary literal parse so our sockets don't blow up on disconnect
				if(TempStr.regionMatches(0, "ERROR :Closing Link:", 0, 20)) {
					Sock.close();
					break;
				}
			}
			
			// Auto-login
			if(Login == false) {
				// For connection:
    			String nick = Prefs.getString("nick", "DroidIRC-Anon");
    			String user = Prefs.getString("user", "DroidIRC-User");
    			String real = Prefs.getString("real", "DroidIRC-User");
    			
    			// Quick/easy login :)
    			if(Sock != null) {
    				Sock.write("NICK "+nick+"\n");
    				Sock.write("USER "+user+" * 8 :"+real+"\n");
    			}
    			
    			Login = true;
			}
			try {
				Thread.sleep(25); // 25 ms wait - don't kill the CPU/phone battery
			} catch (InterruptedException e) {
				break; // Break the loop
			}
		}
	}//run()

	//This group of functions parses incoming messages. "ServerHandler" handles messages from the server,
	//and "UserHandler" handles messages from users.
	private void interpret(){
		if(TempStr.charAt(0) == ':'){
			if(first){
				ServerName = TempStr.substring(1,TempStr.indexOf(' ')); 
				System.out.println("CLIENT: ServerName set to " + ServerName);
				first = false; 
			}
			if(TempStr.substring(1,TempStr.indexOf(' ')).equals(ServerName) || TempStr.substring(1,TempStr.indexOf(' ')).equals(Prefs.getString("nick", "DroidIRC-Anon")))
				ServerHandler();
			else UserHandler();
		}
	}
	
	private void getNames()
	{
		NameReq = true;
	}
	
	private void ServerHandler(){
		System.out.println("Handling server message...");
		target = "server";
		int end = TempStr.indexOf(':',1);
		int space = TempStr.indexOf(' ');
		String msgcode = TempStr.substring(space+1, TempStr.indexOf(' ', space+1));
		line = "["+msgcode+"]"+TempStr.substring(end+1,TempStr.length());
		
		if(msgcode.equals("353")) { /* Update nicklist */
			final TextView nicklist = (TextView)Activity.findViewById(R.id.nicklist);
			final String [] nicks = TempStr.substring(end).split(" ");
			
			Handle.post(new Runnable() {
				@Override
				public void run() {
					String newlist = new String();
					for(int i = 0 ; i < nicks.length ; ++i) {
						if(!nicks[i].contains("#") && nicks[i].length() > 0)
							if(nicks[i].contains(":"))
								newlist += nicks[i].substring(1)+"\n";
							else		
								newlist += nicks[i].substring(0)+"\n";
					}
					nicklist.setText(newlist);
				}
			});
		}//'NAMES' message
	}

	private void UserHandler(){
		System.out.println("Handling user message...");
		int end = TempStr.indexOf(':',1);
		String[] words = {"","","",""};
		String sender = "";
		String message = "";
		//preliminary parsing
		words = TempStr.trim().split(" ");
		System.out.println("Words[0] = " + words[0] + " Words[1] = |" + words[1] + "|");
		int end2;
		if( (end2 = words[0].indexOf('!')) > 0)sender = words[0].substring(1, end2);
		if(end>0) message = TempStr.substring(end+1);		
		String nick = Prefs.getString("nick", "DroidIRC-Anon");
		
		if(TempStr.charAt(end+1) == '\u0001')
			line = message.replaceFirst("ACTION",sender);
		else if(words[1].toUpperCase().equals("QUIT")){
			line = sender + " quit IRC ("+message+")";
			System.out.println("Should see " + line);
		}
		else if(words[1].toUpperCase().equals("JOIN")){
			if(sender.equals(nick)){//This client joined a channel; open new window
				final String name = words[2];
				Handle.post(new Runnable() {
					@Override
					public void run() {
						Activity.setNewView(name);
					}
				});
			}
			else{
				target = words[2];
				line = sender + " joined " + words[2];
			}
		}
		else if(words[1].toUpperCase().equals("SERVER")) { /* Try to do multiple servers maybe */
			Thread thread;
			ClientSocket sock;
			try {
				sock = new ClientSocket(words[2], 6667);
			} catch (IOException e) {
				return;
			}
			thread = new ReaderThread(sock, Handle, Prefs, Activity);
			thread.start();
		}
		else if(words[1].toUpperCase().equals("PART")){
			if(sender.equals(nick)){//This client parted a channel; close the window
				final String name = words[2];
				Handle.post(new Runnable() {
					@Override
					public void run() {
						Activity.removeView(name);
					}
				});
			}
			target = words[2];
			line = sender + " has departed from " + words[2];
		}
		else if(words[1].toUpperCase().equals("PRIVMSG")){			
			target = words[2];
			line = "<"+sender+">"+ message;
		}
	}
}
